/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ca.ubc.icapture.genapha.actions;

import ca.ubc.icapture.genapha.forms.GeneSnpForm;
import icapture.SQLMgr;
import icapture.beans.DB.Gene;
import icapture.beans.DB.KeggPathway;
import icapture.genapha.GenaphaTools;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jxl.read.biff.BiffException;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.Action;
import jxl.*;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMessage;
import org.biomoby.services.ncbi.NCBIJobManager;
import org.biomoby.services.ncbi.jobs.ChrRangeByGeneInfoFromXML;
import org.biomoby.services.ncbi.jobs.GeneInformationByEGeneID_GeneName;
import org.biomoby.services.ncbi.jobs.SnpBySnpInformationFromXML;
import org.biomoby.services.ncbi.jobs.SnpInformationByChrRangeFromXML;

/**
 *
 * @author ATan1
 */
public class GenePathwayAction extends Action {

    private String schema;
    private int offset = 0;
    private TreeSet<Gene> geneList;

    @Override
    public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response) {
        ActionErrors errors = new ActionErrors();
        ActionForward forward = new ActionForward();

        HashMap<KeggPathway, TreeSet<Gene>> pathwayGeneMap = new HashMap<KeggPathway, TreeSet<Gene>>();
        GeneSnpForm geneSnpForm = (GeneSnpForm) form;
        geneSnpForm.setPathwayGeneMap(pathwayGeneMap);

        if (geneSnpForm.getSubmitType().isEmpty()) {
            return mapping.findForward("display");
        }
        geneList = new TreeSet<Gene>();
        geneSnpForm.setGeneList(geneList);
        if (geneSnpForm.getSubmitType().equalsIgnoreCase("Download")) {
            return mapping.findForward("export");
        }
        if (geneSnpForm.getUseTextarea().equals("text")) {
            ByteArrayInputStream bais = new ByteArrayInputStream(geneSnpForm.getTextInput().getBytes());
            ArrayList<String> inputContents = GenaphaTools.readFile(bais);
            readFile(inputContents, " ");
            forward = mapping.findForward("next");
        } //read in the file
        else if (geneSnpForm.getFile() != null) {
            try {
                ArrayList<String> fileContents = GenaphaTools.readFile(geneSnpForm.getFile().getInputStream());
                offset = geneSnpForm.getStreamOffset();

                //check for the content type, tab or comma or excel
                switch (determineFileType(fileContents.get(0))) {
                    case 0:
                        readFile(fileContents, ",");
                        break;
                    case 1:
                        readFile(fileContents, "\t");
                        break;
                    case 2:
                        readExcelFile(geneSnpForm.getFile().getInputStream());
                        break;
                }
            } catch (Exception ex) {
                errors.add("geneSnp", new ActionMessage("geneSnp.error.readingFile"));
                forward = mapping.findForward("error");
            }
        }

        for (Gene gene : geneList) {
            ArrayList<KeggPathway> pathwayList = SQLMgr.getKeggPathways(gene.getEntrezGeneID());
            for (KeggPathway kp : pathwayList) {
                TreeSet geneSet = pathwayGeneMap.get(kp);
                if (geneSet == null) {
                    geneSet = new TreeSet<Gene>();
                    pathwayGeneMap.put(kp, geneSet);
                }
                geneSet.add(gene);
            }
        }

        forward = mapping.findForward("next");

        if (geneSnpForm.getExcel()) {
            forward = mapping.findForward("export");
        }

        saveErrors(request, errors);
        return forward;
    }

    private int determineFileType(String testLine) {
        if (testLine.split(",").length == 2) {
            return 0;
        } else if (testLine.split("\t").length == 2) {
            return 1;
        } else {
            return 2;
        }
    }

    private void readFile(ArrayList<String> fileContents, String delimiter) {

        for (String line : fileContents) {
            try {

                String[] lineSp = line.split(delimiter);

                Gene gene = new Gene();
                gene.setEntrezGeneID(Integer.parseInt(lineSp[0]));
                gene.setName(lineSp[1]);
                gene.setGeneID(gene.getEntrezGeneID()); //set gene id so compares will work

                geneList.add(gene);

            } catch (Exception ex) {
                Logger.getLogger(GeneSnpAction.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void readExcelFile(InputStream in) throws BiffException, IOException, Exception {

        Workbook wb = Workbook.getWorkbook(in);
        Sheet sheet = wb.getSheet(0);
        Cell[] first = sheet.getColumn(0);
        Cell[] second = sheet.getColumn(1);
        for (int i = 0; i < first.length; ++i) {

            Gene gene = new Gene();
            gene.setEntrezGeneID(Integer.parseInt(first[i].getContents()));
            gene.setName(second[i].getContents());
            gene.setGeneID(gene.getEntrezGeneID()); //set gene id so compares will work

            geneList.add(gene);

        }
    }
}
